function createCanvas(id) {
  const canvas = document.getElementById(id);
  const context = canvas.getContext('2d');
  context.translate(0.5, 0.5); // 画布坐标偏移，优化 1px 显示效果

  let config = {}; // 参数配置
  let painting = false; // 操作画布标识：true - 可操作，false - 不可操作
  let clear = false; // 擦除标识：true - 擦除画布，false - 绘制画布

  // 手动绘制方法
  const draw = (layerX, layerY) => {
    // 参数验证
    if (!config.size || !config.data) {
      return false;
    }

    // 根据鼠标位置计算系统运行数据坐标
    const x = Math.floor(layerX / config.size);
    const y = Math.floor(layerY / config.size);

    // 同步设置系统运行数据状态
    config.data.set(MakeKey(x, y), !clear);
    // 更新画布
    execute(x, y, !clear);

    return true;
  };

  // 鼠标按下，可操作画布
  canvas.onmousedown = () => (painting = true);
  // 鼠标抬起，不可操作画布
  canvas.onmouseup = () => (painting = false);
  // 鼠标移出画布，不可操作画布
  canvas.onmouseleave = () => (painting = false);
  // 鼠标按下且移动，手动绘制画布
  canvas.onmousemove = e => {
    if (painting === true) draw(e.layerX, e.layerY);
  };
  // 鼠标左键点击，手动绘制画布
  canvas.onclick = e => {
    clear = false; // 绘制
    draw(e.layerX, e.layerY);
  };
  // 鼠标右键点击，手动绘制画布
  canvas.oncontextmenu = e => {
    e.preventDefault(); // 取消默认操作
    clear = true; // 擦除
    draw(e.layerX, e.layerY);
  };

  // 画布初始化方法
  const init = () => {
    const { border, data } = config;
    context.strokeStyle = border; // 设置细胞边框颜色
    context.lineWidth = 1; // 设置细胞边框宽度

    // 绘制细胞状态
    IterateCells(config, (x, y) => {
      execute(x, y, data.get(MakeKey(x, y)));
      return true;
    });

    return true;
  };

  // 设置画布
  function setCanvas(_config) {
    // 参数验证
    if (getType(_config) !== 'object') {
      throw new Error('config must be an object!');
    }
    if (getType(_config.data) !== 'map') {
      throw new Error('data must be a map!');
    }
    // 创建参数副本
    config = _config;

    // 设置画布尺寸
    const width = config.width * config.size + 1;
    const height = config.height * config.size + 1;
    if (canvas.width !== width) canvas.width = width;
    if (canvas.height !== height) canvas.height = height;
    // 设置画布背景色
    canvas.style.backgroundColor = config.dead;
    // 画布初始化
    init();

    return true;
  }

  // 清空画布
  function clearCanvas() {
    canvas.height = canvas.height;
    // 清空系统运行数据
    config.data = new Map();
    // 画布初始化
    init();

    return true;
  }

  // 更新画布
  function execute(x, y, life) {
    const { size, alive, dead } = config;
    // 设置细胞颜色
    context.fillStyle = life ? alive : dead;
    // 绘制细胞，细胞间距 1px
    context.fillRect(x * size + 1, y * size + 1, size - 1, size - 1);

    return true;
  }

  // 对外暴露系统方法
  return { setCanvas, clearCanvas, execute };
}
